package com.xc.simpleReflect.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xc.simpleReflect.Enums.WrapQuery;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class SimpleReflect {
    public static <T> QueryWrapper parseWrap(Object sour, Class<T> cla) {
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.setEntityClass(cla);
        //获取原对象字节码文件
        Class<?> sCla = sour.getClass();
        //获取全部成员变量
        Field[] fields = sCla.getDeclaredFields();
        // 遍历field数组
        for (Field field : fields) {
            //判断是否包含注解
            if (field.isAnnotationPresent(WrapQuery.class)) {
                // 获取field的值
                Object value = getVal(field, sour);
                // 获取属性名
                String col = getName(field);
                // 拼接QueryWrapper
                getWrap(wrapper, col, value, field);
            }
        }
        return wrapper;
    }

    private static void getWrap(QueryWrapper wrapper, String col, Object value, Field field) {
        // 校验value。暂时都不能为null，为empty吧。还差type = isNull之类的
        if (Objects.isNull(value)) {
            return;
        } else if (value instanceof String && !StringUtils.hasText((String) value)) {
            return;
        } else if (value instanceof Object[] && ((Object[]) value).length <= 0) {
            return;
        } else if (value instanceof Collection && CollectionUtils.isEmpty((Collection<?>) value)) {
            return;
        }
        // 根据type拼接wrapper
        WrapQuery annotation = field.getAnnotation(WrapQuery.class);
        switch (annotation.type()) {//jdk 12以上，可以使用箭头表达式
            case EQ:
                wrapper.eq(col, value);
                break;
            case GE:
                wrapper.ge(col, value);
                break;
            case GT:
                wrapper.gt(col, value);
                break;
            case LE:
                wrapper.le(col, value);
                break;
            case LT:
                wrapper.lt(col, value);
                break;
            case LIKE:
                wrapper.like(col, value);
                break;
            case NOTLIKE:
                wrapper.notLike(col, value);
                break;
            case IN:
                if (value instanceof Collection) {
                    wrapper.in(col, (Collection<?>) value);
                } else if (value instanceof Object[]) {
                    List<Object> list = Arrays.stream((Object[]) value)
                            .collect(Collectors.toList());
                    wrapper.in(col, list);
                } else {
                    wrapper.in(col, List.of(value));//零散数据T...
                }
                break;
            case NOTIN:
                if (value instanceof Collection) {
                    wrapper.notIn(col, (Collection<?>) value);
                } else if (value instanceof Object[]) {
                    List<Object> list = Arrays.stream((Object[]) value)
                            .collect(Collectors.toList());
                    wrapper.notIn(col, list);
                } else {
                    wrapper.notIn(col, List.of(value));//零散数据:T...
                }
                break;
            case LIKELEFT:
                wrapper.likeLeft(col, value);
                break;
            case NOTLIKELEFT:
                wrapper.notLikeLeft(col, value);
                break;
            case LIKERIGHT:
                wrapper.likeRight(col, value);
                break;
            case NOTLIKERIGHT:
                wrapper.notLikeRight(col, value);
                break;
        }
    }

    private static String getName(Field field) {
        String name = field.getName();
        WrapQuery annotation = field.getAnnotation(WrapQuery.class);
        if (StringUtils.hasText(annotation.name())) {
            name = annotation.name();
        }
        return name;
    }

    private static Object getVal(Field field, Object sour) {//可以用PropertyDescriptor实现
        // 关闭校验
        field.setAccessible(true);
        Object val = null;
        try {
            val = field.get(sour);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
/*      // PropertyDescriptor实现
        Object val = null;
        try {
            PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), sour.getClass());
            Method read = descriptor.getReadMethod();
            val = read.invoke(sour);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }*/
        return val;
    }
}
